﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.CApCableAttachmentStatusAnalysis
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using System;
using System.Collections.Generic;
using System.Linq;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.PrivateImplementationDetails;


namespace DnProcessSimulateCommands;

public class CApCableAttachmentStatusAnalysis
{
  internal CApCableAttachmentStatusAnalysis(
    ICApFLEXCableAttributeViewModel attributeViewModel,
    CApFLEXCableAttachmentViewModel attachmentViewModel,
    CApCableFrameAttachmentRetriever frameAttachmentRetriever)
  {
    this.AttachmentViewModel = attachmentViewModel;
    this.AttributeViewModel = attributeViewModel;
    this.CableFrameAttachmentRetriever = frameAttachmentRetriever;
  }

  public ICApFLEXCableAttributeViewModel AttributeViewModel { get; set; }

  public CApFLEXCableAttachmentViewModel AttachmentViewModel { get; private set; }

  internal CApCableFrameAttachmentRetriever CableFrameAttachmentRetriever { get; private set; }

  public double CableRadius => this.AttributeViewModel.Radius;

  public double CableLength => this.AttributeViewModel.Length;

  public double CableFulcrumLength => this.AttributeViewModel.FulcrumLength;

  public ITxLocatableObject StartFrame => this.AttributeViewModel.StartFrame;

  public ITxLocatableObject EndFrame => this.AttributeViewModel.EndFrame;

  public ITxLocatableObject FixedFrame => this.AttachmentViewModel.FixedFrame;

  public ITxLocatableObject SecondaryFixedFrame => this.AttachmentViewModel.SecondaryFixedFrame;

  public ITxLocatableObject ClosestFrameToStart
  {
    get
    {
      return this.AttachmentType != CApFLEXAttachmentType.RetractSystemType3 ? this.FixedFrame : this.SecondaryFixedFrame;
    }
  }

  public List<CApFLEXAttachment> AttachmentDataList => this.AttributeViewModel.RawAttachmentList();

  public CApFLEXAttachmentType AttachmentType => this.AttachmentViewModel.AttachmentType;

  public CApFLEXAttachmentLocation Location => this.AttachmentViewModel.Location;

  public double LengthFromStart => this.AttachmentViewModel.LengthFromStart;

  public double SecondaryLengthFromStart => this.AttachmentViewModel.SecondaryLengthFromStart;

  public double LowerLengthFromStart
  {
    get
    {
      return this.AttachmentType != CApFLEXAttachmentType.RetractSystemType3 ? this.LengthFromStart : this.SecondaryLengthFromStart;
    }
  }

  public double RetractionCapability
  {
    get
    {
      double retractionCapability = 0.0;
      if (this.AttachmentType == CApFLEXAttachmentType.RetractSystemType2 || this.AttachmentType == CApFLEXAttachmentType.RetractSystemType3)
        retractionCapability = this.AttachmentViewModel.MaxRetractedLength - this.AttachmentViewModel.MinRetractedLength;
      return retractionCapability;
    }
  }

  public CApFLEXAttachmentErrorMessage.EAttachmentErrorType MinimumDistanceErrorType
  {
    get
    {
      return this.AttachmentType != CApFLEXAttachmentType.RetractSystemType3 ? CApFLEXAttachmentErrorMessage.EAttachmentErrorType.AttachmentDistanceError : CApFLEXAttachmentErrorMessage.EAttachmentErrorType.AttachmentSecondaryDistanceError;
    }
  }

  public double MinimalLengthBetweenAttachments
  {
    get
    {
      return TxCableDataValidator.GetMinimalLengthBetweenAttachments(this.CableRadius, this.CableFulcrumLength);
    }
  }

  public bool AreStartEndFrameAttachedToSameRobot()
  {
    bool sameRobot = true;
    TxRobot robot1 = (TxRobot) null;
    TxRobot robot2 = (TxRobot) null;
    if (this.StartFrame != null)
    {
      sameRobot = true;
      this.CableFrameAttachmentRetriever.RetrieveAttachingRobot(this.StartFrame, out robot1);
      this.CableFrameAttachmentRetriever.RetrieveAttachingRobot(this.EndFrame, out robot2);
      if (TxRobot.op_Inequality(robot1, (ITxObject) robot2) && TxRobot.op_Inequality(robot1, (ITxObject) null) && TxRobot.op_Inequality(robot2, (ITxObject) null))
        sameRobot = false;
    }
    return sameRobot;
  }

  public bool AreAttachmentsAttachedToRobot(ITxObject robot)
  {
    bool robot1 = false;
    TxRobot robot2;
    this.CableFrameAttachmentRetriever.RetrieveAttachingRobot(this.FixedFrame, out robot2);
    if (TxRobot.op_Equality(robot2, robot))
      robot1 = true;
    return robot1;
  }

  public bool AreAttachementFrameValid()
  {
    bool flag = true;
    ITxObject robotFrame1;
    CApCableUtility.ComputeRobotFrameAttachement(this.FixedFrame, out robotFrame1);
    if (robotFrame1 == null)
      flag = false;
    else if (this.AttachmentType == CApFLEXAttachmentType.RetractSystemType3)
    {
      ITxObject robotFrame2 = (ITxObject) null;
      CApCableUtility.ComputeRobotFrameAttachement(this.SecondaryFixedFrame, out robotFrame2);
      if (robotFrame2 == null)
        flag = false;
    }
    return flag;
  }

  public bool GetFramesAttachedToSameKinematicLinkStatus()
  {
    bool kinematicLinkStatus = true;
    ITxObject robotFrame1;
    CApCableUtility.ComputeRobotFrameAttachement(this.FixedFrame, out robotFrame1);
    ITxObject robotFrame2;
    CApCableUtility.ComputeRobotFrameAttachement(this.SecondaryFixedFrame, out robotFrame2);
    if (robotFrame1 != null || robotFrame2 != null)
    {
      if (robotFrame1 == null || robotFrame2 == null)
        kinematicLinkStatus = false;
      else if (robotFrame1 != robotFrame2)
      {
        kinematicLinkStatus = false;
      }
      else
      {
        TxKinematicLink attachedKinematicLink1;
        CApCableUtility.ComputeKinematicLinkFrameAttachment(this.FixedFrame, out attachedKinematicLink1);
        TxKinematicLink attachedKinematicLink2;
        CApCableUtility.ComputeKinematicLinkFrameAttachment(this.SecondaryFixedFrame, out attachedKinematicLink2);
        if (TxKinematicLink.op_Inequality(attachedKinematicLink1, (ITxObject) attachedKinematicLink2))
          kinematicLinkStatus = false;
      }
    }
    return kinematicLinkStatus;
  }

  public bool IsLengthBetweenPrimaryAndSecondaryAttachmentValid(
    out CApFLEXAttachmentErrorMessage errorMessage)
  {
    bool flag = true;
    errorMessage = new CApFLEXAttachmentErrorMessage();
    if (this.AttachmentViewModel.AttachmentType == CApFLEXAttachmentType.RetractSystemType3 && this.AttachmentViewModel.FixedFrame != null && this.AttachmentViewModel.SecondaryFixedFrame != null)
    {
      double distance;
      CApCableUtility.ComputeDistanceBetweenFrames(this.AttachmentViewModel.FixedFrame, this.AttachmentViewModel.SecondaryFixedFrame, out distance);
      if (this.AttachmentViewModel.LengthFromStart - this.AttachmentViewModel.SecondaryLengthFromStart < distance)
      {
        errorMessage.AttachmentType = CApFLEXAttachmentType.RetractSystemType3;
        errorMessage.AttachmentErrorType = CApFLEXAttachmentErrorMessage.EAttachmentErrorType.AttachmentPrimaryAndSecondaryDistanceError;
        errorMessage.DistanceFromAttachment1 = distance;
        errorMessage.AttachFrame1 = ((ITxObject) this.AttachmentViewModel.FixedFrame).Name;
        errorMessage.AttachFrame2 = ((ITxObject) this.AttachmentViewModel.SecondaryFixedFrame).Name;
        flag = false;
      }
    }
    return flag;
  }

  public bool ArePercentageLengthBetweenAttachmentsValid(
    out CApFLEXAttachmentErrorMessage errorMessage)
  {
    bool flag = true;
    errorMessage = new CApFLEXAttachmentErrorMessage()
    {
      AttachmentType = this.AttachmentType
    };
    if (this.Location == CApFLEXAttachmentLocation.AlongCable)
    {
      double betweenAttachments = this.MinimalLengthBetweenAttachments;
      if (this.LengthFromStart < betweenAttachments)
      {
        flag = false;
        errorMessage.DistanceFromAttachment1 = betweenAttachments;
        errorMessage.AttachmentErrorType = CApFLEXAttachmentErrorMessage.EAttachmentErrorType.StartAttachmentPercentageLengthError;
      }
      int currentAttachmentRank = CApCableAttachmentStatusAnalysis.ComputeCurrentAttachmentRank(this.LengthFromStart, this.AttachmentDataList);
      if (this.AttachmentDataList.Count == 0)
      {
        if (this.CableLength - this.LengthFromStart < betweenAttachments)
        {
          flag = false;
          errorMessage.DistanceFromAttachment1 = betweenAttachments;
          errorMessage.AttachmentErrorType = CApFLEXAttachmentErrorMessage.EAttachmentErrorType.AttachmentAttachmentPercentageLengthError;
        }
      }
      else
      {
        if (Math.Abs(this.LengthFromStart - this.AttachmentDataList[currentAttachmentRank].LengthFromStart) < betweenAttachments)
        {
          flag = false;
          errorMessage.DistanceFromAttachment1 = betweenAttachments;
          errorMessage.AttachmentErrorType = CApFLEXAttachmentErrorMessage.EAttachmentErrorType.AttachmentAttachmentPercentageLengthError;
        }
        if (flag && this.AttachmentDataList.Count > 2 && currentAttachmentRank - 1 >= 0 && Math.Abs(this.LengthFromStart - this.AttachmentDataList[currentAttachmentRank - 1].LengthFromStart) < betweenAttachments)
        {
          flag = false;
          errorMessage.DistanceFromAttachment1 = betweenAttachments;
          errorMessage.AttachmentErrorType = CApFLEXAttachmentErrorMessage.EAttachmentErrorType.AttachmentAttachmentPercentageLengthError;
        }
        if (flag)
        {
          flag = this.IsPointAndRetractSystemAttachementDistanceValid(out double _, out double _);
          if (!flag)
          {
            errorMessage.DistanceFromAttachment1 = betweenAttachments;
            errorMessage.AttachmentErrorType = CApFLEXAttachmentErrorMessage.EAttachmentErrorType.AttachmentAttachmentPercentageLengthError;
          }
        }
      }
    }
    return flag;
  }

  public bool AreAttachmentsLengthSmallerThanCableLength()
  {
    bool flag = true;
    if (this.AttachmentDataList != null)
    {
      foreach (CApFLEXAttachment attachmentData in this.AttachmentDataList)
      {
        if (attachmentData.LengthFromStart > this.CableLength)
        {
          flag = false;
          break;
        }
      }
    }
    return flag;
  }

  public bool IsAttachmentOfTypes(List<CApFLEXAttachmentType> attachmentTypes)
  {
    return this.IsAttachmentTypeInTypes(this.AttachmentType, attachmentTypes);
  }

  private bool IsAttachmentTypeInTypes(
    CApFLEXAttachmentType attachmentType,
    List<CApFLEXAttachmentType> attachmentTypes)
  {
    return attachmentTypes.FindIndex((Predicate<CApFLEXAttachmentType>) (t => t == attachmentType)) != -1;
  }

  public bool IsThereSomeAttachmentAtLocation(CApFLEXAttachmentLocation location)
  {
    bool flag = false;
    if (this.AttachmentDataList != null)
    {
      List<CApFLEXAttachment>.Enumerator enumerator = this.AttachmentDataList.GetEnumerator();
      while (!flag && enumerator.MoveNext())
        flag = enumerator.Current.Location == location;
    }
    return flag;
  }

  public bool IsThereSomeAttachmentOfTypes(List<CApFLEXAttachmentType> attachmentTypes)
  {
    return this.AttachmentDataList != null && this.AttachmentDataList.Any<CApFLEXAttachment>((Func<CApFLEXAttachment, bool>) (a => this.IsAttachmentTypeInTypes(a.AttachmentType, attachmentTypes)));
  }

  public bool IsThereSomeAttachmentOfType(CApFLEXAttachmentType attachmentType)
  {
    return this.AttachmentDataList != null && this.AttachmentDataList.Any<CApFLEXAttachment>((Func<CApFLEXAttachment, bool>) (a => a.AttachmentType == attachmentType));
  }

  public bool IsRetractSystemType2MinMaxAndDistanceFromStartValid()
  {
    bool flag = true;
    if (this.AttachmentType == CApFLEXAttachmentType.RetractSystemType2 && (this.AttachmentViewModel.MinRetractedLength >= this.AttachmentViewModel.LengthFromStart || this.AttachmentViewModel.MaxRetractedLength >= this.AttachmentViewModel.LengthFromStart))
      flag = false;
    return flag;
  }

  public bool IsRetractSystemType3MinMaxAndSecondaryDistanceFromStartValid()
  {
    bool flag = true;
    if (this.AttachmentType == CApFLEXAttachmentType.RetractSystemType3 && (this.AttachmentViewModel.MinRetractedLength >= this.AttachmentViewModel.SecondaryLengthFromStart || this.AttachmentViewModel.MaxRetractedLength >= this.AttachmentViewModel.SecondaryLengthFromStart))
      flag = false;
    return flag;
  }

  public bool AreRetractSystemType3DistancesFromStartValid()
  {
    bool flag = true;
    if (this.AttachmentType == CApFLEXAttachmentType.RetractSystemType3 && this.AttachmentViewModel.LengthFromStart <= this.AttachmentViewModel.SecondaryLengthFromStart)
      flag = false;
    return flag;
  }

  public bool IsRetractSystemMinMaxValid()
  {
    bool flag = true;
    if ((this.AttachmentType == CApFLEXAttachmentType.RetractSystemType2 || this.AttachmentType == CApFLEXAttachmentType.RetractSystemType3) && this.AttachmentViewModel.MinRetractedLength >= this.AttachmentViewModel.MaxRetractedLength)
      flag = false;
    return flag;
  }

  public bool IsPointAndRetractSystemAttachementDistanceValid(
    out double lowerBound,
    out double upperBound)
  {
    bool flag = true;
    double betweenAttachments = this.MinimalLengthBetweenAttachments;
    lowerBound = 0.0;
    upperBound = 0.0;
    if (this.AttachmentType == CApFLEXAttachmentType.RetractSystemType2 || this.AttachmentType == CApFLEXAttachmentType.RetractSystemType3)
    {
      List<CApFLEXAttachment>.Enumerator enumerator = this.AttachmentDataList.GetEnumerator();
      while (flag && enumerator.MoveNext())
      {
        if (!(enumerator.Current is CApFLEXRetractSystemAttachment))
        {
          if (this.AttachmentType == CApFLEXAttachmentType.RetractSystemType2)
            flag = CApCableAttachmentStatusAnalysis.IsPointAndRetractSystemAttachementType2DistanceValid(betweenAttachments, this.AttachmentViewModel.MaxRetractedLength, this.AttachmentViewModel.LengthFromStart, enumerator.Current.LengthFromStart, out lowerBound, out upperBound);
          else if (this.AttachmentType == CApFLEXAttachmentType.RetractSystemType3)
            flag = CApCableAttachmentStatusAnalysis.IsPointAndRetractSystemAttachementType3DistanceValid(betweenAttachments, this.AttachmentViewModel.MaxRetractedLength, this.AttachmentViewModel.LengthFromStart, this.AttachmentViewModel.SecondaryLengthFromStart, enumerator.Current.LengthFromStart, out lowerBound, out upperBound);
        }
      }
    }
    else
    {
      CApFLEXRetractSystemAttachmentType2 systemAttachmentType2 = CApCableAttachmentStatusAnalysis.TryGetRetractSystemAttachmentType2(this.AttachmentDataList);
      if (systemAttachmentType2 != null)
      {
        flag = CApCableAttachmentStatusAnalysis.IsPointAndRetractSystemAttachementType2DistanceValid(betweenAttachments, systemAttachmentType2.MaxRetractedLength, systemAttachmentType2.LengthFromStart, this.AttachmentViewModel.LengthFromStart, out lowerBound, out upperBound);
      }
      else
      {
        CApFLEXRetractSystemAttachmentType3 systemAttachmentType3 = CApCableAttachmentStatusAnalysis.TryGetRetractSystemAttachmentType3(this.AttachmentDataList);
        if (systemAttachmentType3 != null)
          flag = CApCableAttachmentStatusAnalysis.IsPointAndRetractSystemAttachementType3DistanceValid(betweenAttachments, systemAttachmentType3.MaxRetractedLength, systemAttachmentType3.LengthFromStart, systemAttachmentType3.SecondaryLengthFromStart, this.AttachmentViewModel.LengthFromStart, out lowerBound, out upperBound);
      }
    }
    return flag;
  }

  public static int ComputeCurrentAttachmentRank(
    double length,
    List<CApFLEXAttachment> orderedAttachmentList)
  {
    int currentAttachmentRank = 0;
    foreach (CApFLEXAttachment orderedAttachment in orderedAttachmentList)
    {
      if (orderedAttachment.LengthFromStart <= length)
        ++currentAttachmentRank;
      else
        break;
    }
    if (currentAttachmentRank == orderedAttachmentList.Count)
      --currentAttachmentRank;
    return currentAttachmentRank;
  }

  public static CApFLEXRetractSystemAttachmentType2 TryGetRetractSystemAttachmentType2(
    List<CApFLEXAttachment> orderedAttachmentList)
  {
    return orderedAttachmentList.Find((Predicate<CApFLEXAttachment>) (a => a is CApFLEXRetractSystemAttachmentType2)) as CApFLEXRetractSystemAttachmentType2;
  }

  public static CApFLEXRetractSystemAttachmentType3 TryGetRetractSystemAttachmentType3(
    List<CApFLEXAttachment> orderedAttachmentList)
  {
    return orderedAttachmentList.Find((Predicate<CApFLEXAttachment>) (a => a is CApFLEXRetractSystemAttachmentType3)) as CApFLEXRetractSystemAttachmentType3;
  }

  public static double ComputeAttachmentSumDistance(
    int rank,
    List<CApFLEXAttachment> orderedAttachmentList)
  {
    double attachmentSumDistance = 0.0;
    for (int index = 0; index < rank; ++index)
      attachmentSumDistance += orderedAttachmentList[index].LengthFromStart;
    return attachmentSumDistance;
  }

  public static string AttachmentErrorMessage(
    CApFLEXAttachmentErrorMessage attachmentErrorMessage)
  {
    return attachmentErrorMessage.GetErrorMessage();
  }

  public static double ComputeValueWithCurrentLinearUnit(double value)
  {
    return value / TxApplication.Options.Units.LinearMultiplier;
  }

  public static bool IsPointAndRetractSystemAttachementType2DistanceValid(
    double minimalLengthBetweenAttachment,
    double maxRetractLength,
    double distanceFromStartRectactSystemType2,
    double distanceFromStartFixed,
    out double lowerBound,
    out double upperBound)
  {
    bool flag = true;
    lowerBound = distanceFromStartRectactSystemType2 - maxRetractLength - minimalLengthBetweenAttachment;
    upperBound = distanceFromStartRectactSystemType2 + minimalLengthBetweenAttachment;
    if (lowerBound <= distanceFromStartFixed && distanceFromStartFixed <= upperBound)
      flag = false;
    return flag;
  }

  public static bool IsPointAndRetractSystemAttachementType3DistanceValid(
    double minimalLengthBetweenAttachment,
    double maxRetractLength,
    double primaryDistanceFromStart,
    double secondaryDistanceFromStart,
    double distanceFromStartFixed,
    out double lowerBound,
    out double upperBound)
  {
    bool flag = true;
    lowerBound = secondaryDistanceFromStart - maxRetractLength - minimalLengthBetweenAttachment;
    upperBound = primaryDistanceFromStart + minimalLengthBetweenAttachment;
    if (lowerBound <= distanceFromStartFixed && distanceFromStartFixed <= upperBound)
      flag = false;
    return flag;
  }

  public bool IsEquipmentAttachmentFramePreserved(out CApFLEXAttachmentErrorMessage errorMessage)
  {
    bool flag = true;
    errorMessage = new CApFLEXAttachmentErrorMessage();
    if (this.FixedFrame is ITxDetailedRepresentation fixedFrame && fixedFrame.CanPreserved() && !fixedFrame.Preserved)
    {
      errorMessage.AttachmentErrorType = CApFLEXAttachmentErrorMessage.EAttachmentErrorType.AttachmentEquipmentFrameIsNotPreserved;
      errorMessage.AttachFrame1 = ((ITxObject) this.FixedFrame).Name;
      flag = false;
    }
    return flag;
  }
}
